package com.xcity.game.buff;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.xcity.db.entity.Player;
import com.xcity.pomelo.push.msg.BuffsPush;

import naga.x.App;
import naga.x.common.Updatable;
import naga.x.game.template.TemplateService;
import naga.x.game.time.TimeUpdater;

public class BuffManager implements Updatable {

	private Player owner;
	private List<Buff> buffs;
	private long lastUpdateTime;
	
	public BuffManager(Player player, List<Buff> buffs) {
		this.owner = player;
		this.buffs = buffs != null ? buffs : new ArrayList<Buff>();
	}

	public Buff addBuff(int buffId) {
		BuffTemplate template = App.getApp().getServiceManager().get(TemplateService.class).get(BuffTemplate.class, buffId);
		if (template == null) {
			return null;
		}
		Buff buff = BuffFactory.create(buffId);
		return addBuff(buff);
	}
	
	public Buff addBuff(Buff buff) {
		merge(buff.getTemplate().getEffectId()); // 移除已有相同效果的buff
		buff.effect(owner);
		buffs.add(buff);
		owner.send(new BuffsPush(buffs));
		return buff;
	}
	
	public Buff removeBuff(int buffId) {
		List<Buff> buffs = this.buffs;
		for (int i = buffs.size() - 1; i >= 0; i--) {
			Buff buff = buffs.get(i);
			if (buff.getId() == buffId) {
				buff = buffs.remove(i);
				buff.uneffect(owner);
				owner.send(new BuffsPush(buffs));
				return buff;
			}
		}
		return null;
	}
	
	private void merge(int effectId) {
		List<Buff> buffs = this.buffs;
		for (int i = buffs.size() - 1; i >= 0; i--) {
			if (buffs.get(i).getTemplate().getEffectId() == effectId) {
				Buff removed = buffs.remove(i);
				removed.uneffect(owner);
				break;
			}
		}
	}
	
	public boolean hasBuffOfEffect(int effectId) {
		List<Buff> buffs = this.buffs;
		for (int i = buffs.size() - 1; i >= 0; i--) {
			if (buffs.get(i).getTemplate().getEffectId() == effectId) {
				return true;
			}
		}
		return false;
	}
	
	public boolean hasBuff(int buffId) {
		List<Buff> buffs = this.buffs;
		for (int i = buffs.size() - 1; i >= 0; i--) {
			if (buffs.get(i).getId() == buffId) {
				return true;
			}
		}
		return false;
	}
	
	public Buff getBuffByEffect(int effectId) {
		List<Buff> buffs = this.buffs;
		for (int i = buffs.size() - 1; i >= 0; i--) {
			Buff buff = buffs.get(i);
			if (buff.getTemplate().getEffectId() == effectId) {
				return buff;
			}
		}
		return null;
	}
	
	public Buff getBuff(int buffId) {
		List<Buff> buffs = this.buffs;
		for (int i = buffs.size() - 1; i >= 0; i--) {
			Buff buff = buffs.get(i);
			if (buff.getId() == buffId) {
				return buff;
			}
		}
		return null;
	}

	public List<Buff> getBuffs() {
		return buffs;
	}
	
	public void setBuffs(List<Buff> buffs) {
		this.buffs = buffs;
	}

	@Override
	public boolean update() {
		long now = TimeUpdater.getInstance().now();
		if (now - lastUpdateTime < 1000) {
			return false;
		}
		lastUpdateTime = now;
		if (buffs.isEmpty()) {
			return true;
		}
		boolean changed = false;
		Buff[] buffArr = buffs.toArray(new Buff[buffs.size()]); // copy一份，避免并发问题
		for (Buff buff : buffArr) {
			if (buff.update()) {
				buffs.remove(buff);
				buff.uneffect(owner);
				changed = true;
			}
		}
		if (changed) {
			owner.send(new BuffsPush(buffs));
		}
		return true;
	}

	@Override
	public String toString() {
		return JSON.toJSONString(buffs);
	}

	public void init(Player player) {
		this.owner = player;
	}

}
